home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume10 / ptoc / part10 < prev    next >
Encoding:
Internet Message Format  |  1987-07-28  |  55.7 KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v10i074:  Pascal to C translator, Part10/12
  5. Message-ID: <727@uunet.UU.NET>
  6. Date: 30 Jul 87 00:30:53 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 2548
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: Per Bergsten <mcvax!enea!chalmers!holtec!perb>
  12. Posting-number: Volume 10, Issue 74
  13. Archive-name: ptoc/Part10
  14.  
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 10 (of 12)."
  23. # Contents:  ptc.p.2
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'ptc.p.2' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'ptc.p.2'\"
  27. else
  28. echo shar: Extracting \"'ptc.p.2'\" \(52771 characters\)
  29. sed "s/^X//" >'ptc.p.2' <<'END_OF_FILE'
  30. X            if sp^.lt = lforwlab then
  31. X                sp^.lt := llabel
  32. X            else
  33. X                error(emuldeflab);
  34. X            end;
  35. X        oldlbl := tp
  36. X    end;
  37. X
  38. X    (*    Parse declaration and statement-body for prog/subs.    *)
  39. X    procedure pbody(tp : treeptr);
  40. X
  41. X    var    tq    : treeptr;
  42. X
  43. X    begin
  44. X        statlvl := statlvl + 1;
  45. X        if currsym.st = slabel then
  46. X            begin
  47. X            tp^.tsublab := plabel;
  48. X            linkup(tp, tp^.tsublab)
  49. X            end
  50. X        else
  51. X            tp^.tsublab := nil;
  52. X        if currsym.st = sconst then
  53. X            begin
  54. X            tp^.tsubconst := pconst;
  55. X            linkup(tp, tp^.tsubconst)
  56. X            end
  57. X        else
  58. X            tp^.tsubconst := nil;
  59. X        if currsym.st = stype then
  60. X            begin
  61. X            tp^.tsubtype := ptype;
  62. X            linkup(tp, tp^.tsubtype)
  63. X            end
  64. X        else
  65. X            tp^.tsubtype := nil;
  66. X        if currsym.st = svar then
  67. X            begin
  68. X            tp^.tsubvar := pvar;
  69. X            linkup(tp, tp^.tsubvar)
  70. X            end
  71. X        else
  72. X            tp^.tsubvar := nil;
  73. X        tp^.tsubsub := nil;
  74. X        tq := nil;
  75. X        while (currsym.st = sproc) or (currsym.st = sfunc) do
  76. X            begin
  77. X            if tq = nil then
  78. X                begin
  79. X                tq := psubs;
  80. X                tp^.tsubsub := tq
  81. X                end
  82. X            else begin
  83. X                tq^.tnext := psubs;
  84. X                tq := tq^.tnext
  85. X                 end
  86. X            end;
  87. X        linkup(tp, tp^.tsubsub);
  88. X        checksymbol([sbegin, seof]);
  89. X        if currsym.st = sbegin then
  90. X            begin
  91. X            tp^.tsubstmt := pbegin(false);
  92. X            linkup(tp, tp^.tsubstmt)
  93. X            end;
  94. X        statlvl := statlvl - 1
  95. X    end;
  96. X
  97. X    (*    Parse program-declaration.                *)
  98. X    function pprogram : treeptr;
  99. X
  100. X    var    tp    : treeptr;
  101. X
  102. X        (*    Parse a program parameter id-list.        *)
  103. X        function pprmlist : treeptr;
  104. X
  105. X        label    999;
  106. X
  107. X        var    tp,
  108. X            tq    : treeptr;
  109. X            din,
  110. X            dut    : idptr;
  111. X
  112. X        begin
  113. X            tp := nil;
  114. X            din := deftab[dinput]^.tidl^.tsym^.lid;
  115. X            dut := deftab[doutput]^.tidl^.tsym^.lid;
  116. X            while (currsym.vid = din) or (currsym.vid = dut) do
  117. X                begin
  118. X                (* ignore input/output as parameters so that
  119. X                   they will be bound to stdin/stdout unless
  120. X                   declared as variables *)
  121. X                if currsym.vid = din then
  122. X                    defnams[dinput]^.lused := true
  123. X                else
  124. X                    defnams[doutput]^.lused := true;
  125. X                nextsymbol([scomma, srpar]);
  126. X                if currsym.st = srpar then
  127. X                    goto 999;
  128. X                nextsymbol([sid])
  129. X                end;
  130. X            tq := newid(currsym.vid);
  131. X            tq^.tsym^.lt := lpointer;
  132. X            tp := tq;
  133. X            nextsymbol([scomma, srpar]);
  134. X            while currsym.st = scomma do
  135. X                begin
  136. X                nextsymbol([sid]);
  137. X                if currsym.vid = din then
  138. X                    defnams[dinput]^.lused := true
  139. X                else if currsym.vid = dut then
  140. X                    defnams[doutput]^.lused := true
  141. X                else begin
  142. X                    tq^.tnext := newid(currsym.vid);
  143. X                    tq := tq^.tnext;
  144. X                    tq^.tsym^.lt := lpointer;
  145. X                     end;
  146. X                nextsymbol([scomma, srpar])
  147. X                end;
  148. X        999:
  149. X            pprmlist := tp
  150. X        end;
  151. X
  152. X    begin    (* pprogram *)
  153. X        enterscope(nil);
  154. X        tp := mknode(npgm);
  155. X        nextsymbol([sid]);
  156. X        tp^.tstat := statlvl;
  157. X        tp^.tsubid := mknode(nid);
  158. X        tp^.tsubid^.tup := tp;
  159. X        tp^.tsubid^.tsym := mksym(lidentifier);
  160. X        tp^.tsubid^.tsym^.lid := currsym.vid;
  161. X        tp^.tsubid^.tsym^.lsymdecl := tp^.tsubid;
  162. X        linkup(tp, tp^.tsubid);
  163. X        nextsymbol([slpar, ssemic]);
  164. X        if currsym.st = slpar then
  165. X            begin
  166. X            nextsymbol([sid]);
  167. X            tp^.tsubpar := pprmlist;
  168. X            linkup(tp, tp^.tsubpar);
  169. X            nextsymbol([ssemic])
  170. X            end
  171. X        else
  172. X            tp^.tsubpar := nil;
  173. X        nextsymbol([slabel, sconst, stype, svar,
  174. X                        sproc, sfunc, sbegin]);
  175. X        pbody(tp);
  176. X        checksymbol([sdot]);
  177. X        tp^.tscope := currscope;
  178. X        leavescope;
  179. X        pprogram := tp
  180. X    end;    (* pprogram *)
  181. X
  182. X    (*    Parse a module.                *)
  183. X    function pmodule : treeptr;
  184. X
  185. X    var    tp    : treeptr;
  186. X
  187. X    begin    (* pmodule *)
  188. X        enterscope(nil);
  189. X        tp := mknode(npgm);
  190. X        tp^.tstat := statlvl;
  191. X        tp^.tsubid := nil;
  192. X        tp^.tsubpar := nil;
  193. X        pbody(tp);
  194. X        checksymbol([ssemic]);
  195. X        tp^.tscope := currscope;
  196. X        leavescope;
  197. X        pmodule := tp
  198. X    end;    (* pmodule *)
  199. X
  200. X
  201. X    (*    Parse label-clause.                    *)
  202. X    function plabel;
  203. X
  204. X    var    tp,
  205. X        tq    : treeptr;
  206. X
  207. X    begin
  208. X        tq := nil;
  209. X        repeat
  210. X            nextsymbol([sinteger]);
  211. X            if tq = nil then
  212. X                begin
  213. X                tq := newlbl;
  214. X                tp := tq
  215. X                end
  216. X            else begin
  217. X                tq^.tnext := newlbl;
  218. X                tq := tq^.tnext;
  219. X                 end;
  220. X            nextsymbol([scomma, ssemic])
  221. X        until    currsym.st = ssemic;
  222. X        nextsymbol([sconst, stype, svar, sbegin, sproc, sfunc]);
  223. X        plabel := tp
  224. X    end;
  225. X
  226. X    (*    Parse an id-list.                    *)
  227. X    function pidlist;
  228. X
  229. X    var    tp,
  230. X        tq    : treeptr;
  231. X
  232. X    begin
  233. X        tq := newid(currsym.vid);
  234. X        tq^.tsym^.lt := l;
  235. X        tp := tq;
  236. X        nextsymbol([scomma, scolon, seq, srpar]);
  237. X        while currsym.st = scomma do
  238. X            begin
  239. X            nextsymbol([sid]);
  240. X            tq^.tnext := newid(currsym.vid);
  241. X            tq := tq^.tnext;
  242. X            tq^.tsym^.lt := l;
  243. X            nextsymbol([scomma, scolon, seq, srpar])
  244. X            end;
  245. X        pidlist := tp
  246. X    end;
  247. X
  248. X    (*    Parse const-clause.                    *)
  249. X    function pconst;
  250. X
  251. X    var    tp,
  252. X        tq    : treeptr;
  253. X
  254. X    begin
  255. X        tq := nil;
  256. X        nextsymbol([sid]);
  257. X        repeat
  258. X            if tq = nil then
  259. X                begin
  260. X                tq := mknode(nconst);
  261. X                tq^.tattr := anone;
  262. X                tp := tq
  263. X                end
  264. X            else begin
  265. X                tq^.tnext := mknode(nconst);
  266. X                tq := tq^.tnext;
  267. X                tq^.tattr := anone
  268. X                 end;
  269. X            tq^.tidl := pidlist(lidentifier);
  270. X            checksymbol([seq]);
  271. X            nextsymbol([sid, schar, sstring, sinteger, sreal,
  272. X                        splus, sminus]);
  273. X            tq^.tbind := pconstant(true);
  274. X            nextsymbol([ssemic]);
  275. X            nextsymbol([sid, stype, svar, sbegin,
  276. X                            sfunc, sproc, seof])
  277. X        until    currsym.st <> sid;
  278. X        pconst := tp
  279. X    end;
  280. X
  281. X    (*    Parse a declared constant or a case-statment const.    *)
  282. X    function pconstant;
  283. X
  284. X    var    tp,
  285. X        tq    : treeptr;
  286. X        neg    : boolean;
  287. X
  288. X    begin
  289. X        neg := currsym.st = sminus;
  290. X        if currsym.st in [splus, sminus] then
  291. X            if realok then
  292. X                nextsymbol([sid, sinteger, sreal])
  293. X            else
  294. X                nextsymbol([sid, sinteger]);
  295. X        if currsym.st = sid then
  296. X            tp := oldid(currsym.vid, lidentifier)
  297. X        else
  298. X            tp := mklit;
  299. X        if neg then
  300. X            begin
  301. X            tq := mknode(numinus);
  302. X            tq^.texps := tp;
  303. X            tp := tq
  304. X             end;
  305. X        pconstant := tp
  306. X    end;
  307. X
  308. X    (*    Parse a record (or record-variant) declaration.        *)
  309. X    (*    Cs is the expected closing symbol, dp the scope.    *)
  310. X    function precord;
  311. X
  312. X    label    999;
  313. X
  314. X    var    tp,
  315. X        tq,
  316. X        tl,
  317. X        tv    : treeptr;
  318. X        tsym    : lexsym;
  319. X
  320. X    begin
  321. X        tp := mknode(nrecord);
  322. X        tp^.tflist := nil;
  323. X        tp^.tvlist := nil;
  324. X        tp^.tuid := nil;
  325. X        tp^.trscope := nil;
  326. X        if cs = send then
  327. X            begin
  328. X            enterscope(dp);
  329. X            dp := currscope
  330. X            end;
  331. X        nextsymbol([sid, scase] + [cs]);
  332. X        tq := nil;
  333. X        while currsym.st = sid do
  334. X            begin
  335. X            if tq = nil then
  336. X                begin
  337. X                tq := mknode(nfield);
  338. X                tq^.tattr := anone;
  339. X                tp^.tflist := tq
  340. X                end
  341. X            else begin
  342. X                tq^.tnext := mknode(nfield);
  343. X                tq := tq^.tnext;
  344. X                tq^.tattr := anone
  345. X                 end;
  346. X            tq^.tidl := pidlist(lfield);
  347. X            checksymbol([scolon]);
  348. X            leavescope;
  349. X            tq^.tbind := ptypedef;
  350. X            enterscope(dp);
  351. X            if currsym.st = ssemic then
  352. X                nextsymbol([sid, scase] + [cs])
  353. X            end;
  354. X        if currsym.st = scase then
  355. X            begin
  356. X            nextsymbol([sid]);
  357. X            tsym := currsym;
  358. X            nextsymbol([scolon, sof]);
  359. X            if currsym.st = scolon then
  360. X                begin
  361. X                tv := newid(tsym.vid);
  362. X                if tq = nil then
  363. X                    begin
  364. X                    tq := mknode(nfield);
  365. X                    tp^.tflist := tq
  366. X                    end
  367. X                else begin
  368. X                    tq^.tnext := mknode(nfield);
  369. X                    tq := tq^.tnext
  370. X                     end;
  371. X                tq^.tidl := tv;
  372. X                tv^.tsym^.lt := lfield;
  373. X                nextsymbol([sid]);
  374. X                leavescope;
  375. X                tq^.tbind := oldid(currsym.vid, lidentifier);
  376. X                enterscope(dp);
  377. X                nextsymbol([sof])
  378. X                end;
  379. X            tq := nil;
  380. X            repeat
  381. X                tv := nil;
  382. X                repeat
  383. X                    nextsymbol([sid, sinteger, schar, splus,
  384. X                             sminus] + [cs]);
  385. X                    if currsym.st = cs then
  386. X                        goto 999;
  387. X                    if tv = nil then
  388. X                        begin
  389. X                        tv := pconstant(false);
  390. X                        tl := tv
  391. X                        end
  392. X                    else begin
  393. X                        tv^.tnext := pconstant(false);
  394. X                        tv := tv^.tnext
  395. X                         end;
  396. X                    nextsymbol([scolon, scomma])
  397. X                until currsym.st = scolon;
  398. X                nextsymbol([slpar]);
  399. X                if tq = nil then
  400. X                    begin
  401. X                    tq := mknode(nvariant);
  402. X                    tp^.tvlist := tq;
  403. X                    end
  404. X                else begin
  405. X                    tq^.tnext := mknode(nvariant);
  406. X                    tq := tq^.tnext;
  407. X                     end;
  408. X                tq^.tselct := tl;
  409. X                tq^.tvrnt := precord(srpar, dp)
  410. X            until    currsym.st = cs
  411. X            end;
  412. X    999:
  413. X        if cs = send then
  414. X            begin
  415. X            tp^.trscope := dp;
  416. X            leavescope
  417. X            end;
  418. X        nextsymbol([ssemic, send, srpar]);
  419. X        (* currsym is the symbol following record end/rpar,
  420. X            (usually semicolon, sometimes enclosing end/rpar) *)
  421. X        precord := tp
  422. X    end;
  423. X
  424. X    function ptypedef;
  425. X
  426. X    var    tp,
  427. X        tq    : treeptr;
  428. X        st    : symtyp;
  429. X        ss    : symset;
  430. X
  431. X    begin
  432. X        nextsymbol([sid, slpar, sarrow, sinteger, schar, splus, sminus,
  433. X                spacked, sarray, srecord, sfile, sset]);
  434. X
  435. X        (* the "packed" keyword is completely ignored *)
  436. X        if currsym.st = spacked then
  437. X            nextsymbol([sarray, srecord, sfile, sset]);
  438. X
  439. X        ss := [ssemic, send, srpar, scomma, srbrack];
  440. X        case currsym.st of
  441. X          splus,
  442. X          sminus,
  443. X          schar,
  444. X          sinteger,
  445. X          sid:
  446. X            begin
  447. X            st := currsym.st;
  448. X            tp := pconstant(false);
  449. X            if st = sid then
  450. X                nextsymbol([sdotdot] + ss)
  451. X            else
  452. X                nextsymbol([sdotdot]);
  453. X            if currsym.st = sdotdot then
  454. X                begin
  455. X                nextsymbol([sid, sinteger, schar,
  456. X                                splus, sminus]);
  457. X                tq := mknode(nsubrange);
  458. X                tq^.tlo := tp;
  459. X                tq^.thi := pconstant(false);
  460. X                tp := tq;
  461. X                nextsymbol(ss)
  462. X                end
  463. X            end;
  464. X          slpar:
  465. X            begin
  466. X            tp := mknode(nscalar);
  467. X            nextsymbol([sid]);
  468. X            tp^.tscalid := pidlist(lidentifier);
  469. X            checksymbol([srpar]);
  470. X            nextsymbol(ss)
  471. X            end;
  472. X          sarrow:
  473. X            begin
  474. X            tp := mknode(nptr);
  475. X            nextsymbol([sid]);
  476. X            tp^.tptrid := oldid(currsym.vid, lpointer);
  477. X            tp^.tptrflag := false;
  478. X            nextsymbol([ssemic, send, srpar])
  479. X            end;
  480. X          sarray:
  481. X            begin
  482. X            nextsymbol([slbrack]);
  483. X            tp := mknode(narray);
  484. X            tp^.taindx := ptypedef;    (* parse subrange ...    *)
  485. X            tq := tp;
  486. X            while currsym.st = scomma do
  487. X                begin
  488. X                (* expand:   array [ A , B ] of X
  489. X                   to:   array [ A ] of array [ B ] of X   *)
  490. X                tq^.taelem := mknode(narray);
  491. X                tq := tq^.taelem;
  492. X                tq^.taindx := ptypedef    (* ... again    *)
  493. X                end;
  494. X            checksymbol([srbrack]);
  495. X            nextsymbol([sof]);
  496. X            tq^.taelem := ptypedef
  497. X            end;
  498. X          srecord:
  499. X            tp := precord(send, nil);
  500. X          sfile,
  501. X          sset:
  502. X            begin
  503. X            if currsym.st = sfile then
  504. X                tp := mknode(nfileof)
  505. X            else begin
  506. X                tp := mknode(nsetof);
  507. X                usesets := true
  508. X                 end;
  509. X            nextsymbol([sof]);
  510. X            tp^.tof := ptypedef
  511. X            end
  512. X        end;
  513. X        (* at this point "currsym" holds the symbol following the type
  514. X           (usually semicolon, sometimes the following end/rpar) *)
  515. X        ptypedef := tp
  516. X    end;
  517. X
  518. X    (*    Parse type-clause.                    *)
  519. X    function ptype;
  520. X
  521. X    var    tp,
  522. X        tq    : treeptr;
  523. X
  524. X    begin
  525. X        tq := nil;
  526. X        nextsymbol([sid]);
  527. X        repeat
  528. X            if tq = nil then
  529. X                begin
  530. X                tq := mknode(ntype);
  531. X                tq^.tattr := anone;
  532. X                tp := tq
  533. X                end
  534. X            else begin
  535. X                tq^.tnext := mknode(ntype);
  536. X                tq := tq^.tnext;
  537. X                tq^.tattr := anone
  538. X                 end;
  539. X            tq^.tidl := pidlist(lidentifier);
  540. X            checksymbol([seq]);
  541. X            tq^.tbind := ptypedef;
  542. X            nextsymbol([sid, svar, sbegin, sfunc, sproc, seof])
  543. X        until    currsym.st <> sid;
  544. X        ptype := tp;
  545. X    end;
  546. X
  547. X    (*    Parse var-clause.                    *)
  548. X    function pvar;
  549. X
  550. X    var    ti,
  551. X        tp,
  552. X        tq    : treeptr;
  553. X
  554. X    begin
  555. X        tq := nil;
  556. X        nextsymbol([sid]);
  557. X        repeat
  558. X            if tq = nil then
  559. X                begin
  560. X                tq := mknode(nvar);
  561. X                tq^.tattr := anone;
  562. X                tp := tq
  563. X                end
  564. X            else begin
  565. X                tq^.tnext := mknode(nvar);
  566. X                tq := tq^.tnext;
  567. X                tq^.tattr := anone
  568. X                 end;
  569. X
  570. X            ti := newid(currsym.vid);
  571. X            tq^.tidl := ti;
  572. X            nextsymbol([scomma, scolon]);
  573. X            while currsym.st = scomma do
  574. X                begin
  575. X                nextsymbol([sid]);
  576. X                ti^.tnext := newid(currsym.vid);
  577. X                ti := ti^.tnext;
  578. X                nextsymbol([scomma, scolon])
  579. X                end;
  580. X
  581. X            tq^.tbind := ptypedef;
  582. X            nextsymbol([sid, sbegin, sfunc, sproc, seof])
  583. X        until    currsym.st <> sid;
  584. X        pvar := tp
  585. X    end;
  586. X
  587. X    (*    Parse subroutine-declaration.                *)
  588. X    function psubs;
  589. X
  590. X    var    tp,            (* return value        *)
  591. X        tv, tq    : treeptr;    (* temporary        *)
  592. X        func    : boolean;    (* true for functions    *)
  593. X        colsem    : symtyp;    (* colon/semicolon    *)
  594. X
  595. X    begin
  596. X        (* parsing function or procedure *)
  597. X        func := currsym.st = sfunc;
  598. X        if func then
  599. X            colsem := scolon
  600. X        else
  601. X            colsem := ssemic;
  602. X
  603. X        (* parse id, it may already be forward declared *)
  604. X        nextsymbol([sid]);
  605. X        tq := newid(currsym.vid);
  606. X        if tq^.tup = nil then
  607. X           begin
  608. X            enterscope(nil);
  609. X            (* id wasn't previously declared, params possible *)
  610. X            if func then
  611. X                tp := mknode(nfunc)
  612. X            else
  613. X                tp := mknode(nproc);
  614. X            tp^.tstat := statlvl;
  615. X            tp^.tsubid := tq;
  616. X            linkup(tp, tq);
  617. X            nextsymbol([slpar, colsem]);
  618. X            if currsym.st = slpar then
  619. X                begin
  620. X                tp^.tsubpar := psubpar;
  621. X                linkup(tp, tp^.tsubpar);
  622. X                nextsymbol([colsem])
  623. X                end
  624. X            else
  625. X                tp^.tsubpar := nil;
  626. X            if func then
  627. X                begin
  628. X                (* parse function type *)
  629. X                nextsymbol([sid]);
  630. X                tp^.tfuntyp := oldid(currsym.vid, lidentifier);
  631. X                nextsymbol([ssemic])
  632. X                end
  633. X            else
  634. X                tp^.tfuntyp := mknode(nempty);
  635. X            linkup(tp, tp^.tfuntyp);
  636. X            nextsymbol([sextern, sforward,
  637. X                    slabel, sconst, stype, svar,
  638. X                            sproc, sfunc, sbegin]);
  639. X           end
  640. X        else begin
  641. X            (* id was forward declared =>
  642. X                pick up declarations from parameterlist *)
  643. X            enterscope(tq^.tup^.tscope);
  644. X            if func then
  645. X                tp := mknode(nfunc)
  646. X            else
  647. X                tp := mknode(nproc);
  648. X            tp^.tfuntyp := tq^.tup^.tfuntyp;
  649. X            (* steal id and params from forward decl *)
  650. X            tv := tq^.tup^.tsubpar;
  651. X            tp^.tsubpar := tv;
  652. X            while tv <> nil do
  653. X                begin
  654. X                tv^.tup := tp;
  655. X                tv := tv^.tnext
  656. X                end;
  657. X            tp^.tsubid := tq;
  658. X            tq^.tup := tp;
  659. X            (* id was forward declared =>
  660. X                no params, no function type, no forward *)
  661. X            nextsymbol([ssemic]);
  662. X            nextsymbol([slabel, sconst, stype, svar,
  663. X                            sproc, sfunc, sbegin]);
  664. X             end;
  665. X        if currsym.st in [sforward, sextern] then
  666. X            begin
  667. X            tp^.tsubid^.tsym^.lt := lforward;
  668. X            nextsymbol([ssemic]);
  669. X            tp^.tsublab := nil;
  670. X            tp^.tsubconst := nil;
  671. X            tp^.tsubtype := nil;
  672. X            tp^.tsubvar := nil;
  673. X            tp^.tsubsub := nil;
  674. X            tp^.tsubstmt := nil
  675. X            end
  676. X        else
  677. X            pbody(tp);
  678. X        nextsymbol([sproc, sfunc, sbegin, seof]);
  679. X        tp^.tscope := currscope;
  680. X        leavescope;
  681. X        psubs := tp
  682. X    end;
  683. X
  684. X    (*    Parse a conformant array index type.            *)
  685. X    function pconfsub : treeptr;
  686. X
  687. X    var    tp    : treeptr;
  688. X
  689. X    begin
  690. X        tp := mknode(nsubrange);
  691. X        nextsymbol([sid]);
  692. X        tp^.tlo := newid(currsym.vid);
  693. X        nextsymbol([sdotdot]);
  694. X        nextsymbol([sid]);
  695. X        tp^.thi := newid(currsym.vid);
  696. X        nextsymbol([scolon]);
  697. X        pconfsub := tp
  698. X    end;
  699. X
  700. X    (*    Parse a conformant array-declaration.            *)
  701. X    function pconform : treeptr;
  702. X
  703. X    var    tp, tq    : treeptr;
  704. X
  705. X    begin
  706. X        nextsymbol([slbrack]);
  707. X        tp := mknode(nconfarr);
  708. X        tp^.tcuid := mkvariable('S');
  709. X        tp^.tcindx := pconfsub;    (* parse subrange ...    *)
  710. X        nextsymbol([sid]);
  711. X        tp^.tindtyp := oldid(currsym.vid, lidentifier);
  712. X        nextsymbol([ssemic, srbrack]);
  713. X        tq := tp;
  714. X        while currsym.st = ssemic do
  715. X            begin
  716. X            error(econfconf); (* what size does tp have *)
  717. X
  718. X            (* expand:   array [ A ; B ] of X
  719. X               to:   array [ A ] of array [ B ] of X   *)
  720. X            tq^.tcelem := mknode(nconfarr);
  721. X            tq := tq^.tcelem;
  722. X            tq^.tcindx := pconfsub;    (* ... again    *)
  723. X            nextsymbol([sid]);
  724. X            tq^.tindtyp := oldid(currsym.vid, lidentifier);
  725. X            nextsymbol([ssemic, srbrack])
  726. X            end;
  727. X        nextsymbol([sof]);
  728. X        nextsymbol([sid, sarray]);
  729. X        case currsym.st of
  730. X          sid:
  731. X            tq^.tcelem := oldid(currsym.vid, lidentifier);
  732. X          sarray: 
  733. X            begin
  734. X            error(econfconf); (* what size does tp have *)
  735. X
  736. X            tq^.tcelem := pconform
  737. X            end;
  738. X        end;(* case *)
  739. X        pconform := tp
  740. X    end;
  741. X
  742. X    (*    Parse subroutine parameter list.            *)
  743. X    function psubpar;
  744. X
  745. X    var    tp,
  746. X        tq    : treeptr;
  747. X        nt    : treetyp;
  748. X
  749. X    begin
  750. X        tq := nil;
  751. X        repeat
  752. X            nextsymbol([sid, svar, sfunc, sproc]);
  753. X            case currsym.st of
  754. X              sid:
  755. X                nt := nvalpar;
  756. X              svar:
  757. X                nt := nvarpar;
  758. X              sfunc:
  759. X                nt := nparfunc;
  760. X              sproc:
  761. X                nt := nparproc;
  762. X            end;
  763. X            if nt <> nvalpar then
  764. X                nextsymbol([sid]);
  765. X            if tq = nil then
  766. X                begin
  767. X                tq := mknode(nt);
  768. X                tp := tq
  769. X                end
  770. X            else begin
  771. X                tq^.tnext := mknode(nt);
  772. X                tq := tq^.tnext
  773. X                 end;
  774. X            case nt of
  775. X              nvarpar,
  776. X              nvalpar:
  777. X                begin
  778. X                tq^.tidl := pidlist(lidentifier);
  779. X                tq^.tattr := anone;
  780. X                checksymbol([scolon]);
  781. X                if nt = nvalpar then
  782. X                    nextsymbol([sid])
  783. X                else
  784. X                    nextsymbol([sid, sarray]);
  785. X                case currsym.st of
  786. X                  sid:
  787. X                    tq^.tbind :=
  788. X                        oldid(currsym.vid, lidentifier);
  789. X                  sarray:
  790. X                    tq^.tbind := pconform
  791. X                end;(* case *)
  792. X                nextsymbol([srpar, ssemic])
  793. X                end;
  794. X              nparproc:
  795. X                begin
  796. X                tq^.tparid := newid(currsym.vid);
  797. X                nextsymbol([ssemic, slpar, srpar]);
  798. X                if currsym.st = slpar then
  799. X                    begin
  800. X                    enterscope(nil);
  801. X                    tq^.tparparm := psubpar;
  802. X                    nextsymbol([ssemic, srpar]);
  803. X                    leavescope
  804. X                    end
  805. X                else
  806. X                    tq^.tparparm := nil;
  807. X                tq^.tpartyp := nil
  808. X                end;
  809. X              nparfunc:
  810. X                begin
  811. X                tq^.tparid := newid(currsym.vid);
  812. X                nextsymbol([scolon, slpar]);
  813. X                if currsym.st = slpar then
  814. X                    begin
  815. X                    enterscope(nil);
  816. X                    tq^.tparparm := psubpar;
  817. X                    nextsymbol([scolon]);
  818. X                    leavescope
  819. X                    end
  820. X                else
  821. X                    tq^.tparparm := nil;
  822. X                nextsymbol([sid]);
  823. X                tq^.tpartyp := oldid(currsym.vid, lidentifier);
  824. X                nextsymbol([srpar, ssemic])
  825. X                end
  826. X            end (* case *)
  827. X        until    currsym.st = srpar;
  828. X        psubpar := tp
  829. X    end;
  830. X
  831. X    (*    Parse a (possibly labeled) statement.            *)
  832. X    function plabstmt;
  833. X
  834. X    var    tp    : treeptr;
  835. X
  836. X    begin
  837. X        nextsymbol([sid, sinteger, sif, swhile, srepeat, sfor, scase,
  838. X                  swith, sbegin, sgoto,
  839. X                    selse, ssemic, send, suntil]);
  840. X        if currsym.st = sinteger then
  841. X            begin
  842. X            tp := mknode(nlabstmt);
  843. X            tp^.tlabno := oldlbl(true);
  844. X            nextsymbol([scolon]);
  845. X            nextsymbol([sid, sif, swhile, srepeat, sfor, scase,
  846. X                  swith, sbegin, sgoto,
  847. X                    selse, ssemic, send, suntil]);
  848. X            tp^.tstmt := pstmt
  849. X            end
  850. X        else
  851. X            tp := pstmt;
  852. X        plabstmt := tp
  853. X    end;
  854. X
  855. X    (*    Parse an unlabeled statement.                *)
  856. X    function pstmt;
  857. X
  858. X    var    tp    : treeptr;
  859. X
  860. X    begin
  861. X        case currsym.st of
  862. X          sid:
  863. X            tp := psimple;
  864. X          sif:
  865. X            tp := pif;
  866. X          swhile:
  867. X            tp := pwhile;
  868. X          srepeat:
  869. X            tp := prepeat;
  870. X          sfor:
  871. X            tp := pfor;
  872. X          scase:
  873. X            tp := pcase;
  874. X          swith:
  875. X            tp := pwith;
  876. X          sbegin:
  877. X            tp := pbegin(true);
  878. X          sgoto:
  879. X            tp := pgoto;
  880. X          send,
  881. X          selse,
  882. X          suntil,
  883. X          ssemic:
  884. X            tp := mknode(nempty);
  885. X        end;
  886. X        pstmt := tp
  887. X    end;
  888. X
  889. X    (*    Parse an assignment or a procedure call.        *)
  890. X    function psimple;
  891. X
  892. X    var    tq,
  893. X        tp    : treeptr;
  894. X
  895. X    begin
  896. X        tp := pvariable(oldid(currsym.vid, lidentifier));
  897. X        if currsym.st = sassign then
  898. X            begin
  899. X            tq := mknode(nassign);
  900. X            tq^.tlhs := tp;
  901. X            tq^.trhs := pexpr(nil);
  902. X            tp := tq
  903. X            end;
  904. X        psimple := tp
  905. X    end;
  906. X
  907. X    (*    Parse a varable-reference (or a subroutine-call).    *)
  908. X    function pvariable;
  909. X
  910. X    var    tp,
  911. X        tq    : treeptr;
  912. X
  913. X    begin
  914. X        nextsymbol([slpar, slbrack, sdot, sarrow,
  915. X            sassign, ssemic, scomma, scolon, sdotdot,
  916. X            splus, sminus, smul, sdiv, smod, squot,
  917. X            sand, sor, sinn, srpar, srbrack,
  918. X            sle, slt, seq, sge, sgt, sne,
  919. X            send, suntil, sthen, selse, sdo, sdownto, sto, sof]);
  920. X        if currsym.st in [slpar, slbrack, sdot, sarrow] then
  921. X            begin
  922. X            case currsym.st of
  923. X              slpar:
  924. X                begin
  925. X                tp := mknode(ncall);
  926. X                tp^.tcall := varptr;
  927. X                tq := nil;
  928. X                repeat
  929. X                    if tq = nil then
  930. X                        begin
  931. X                        tq := pexpr(nil);
  932. X                        tp^.taparm  := tq
  933. X                        end
  934. X                    else begin
  935. X                        tq^.tnext := pexpr(nil);
  936. X                        tq := tq^.tnext
  937. X                         end;
  938. X                until    currsym.st = srpar
  939. X                end;
  940. X              slbrack:
  941. X                begin
  942. X                tq := varptr;
  943. X                repeat
  944. X                    tp := mknode(nindex);
  945. X                    tp^.tvariable := tq;
  946. X                    tp^.toffset := pexpr(nil);
  947. X                    tq := tp
  948. X                until    currsym.st = srbrack
  949. X                end;
  950. X              sdot:
  951. X                begin
  952. X                tp := mknode(nselect);
  953. X                tp^.trecord := varptr;
  954. X                nextsymbol([sid]);
  955. X                tq := typeof(varptr);
  956. X                enterscope(tq^.trscope);
  957. X                tp^.tfield := oldid(currsym.vid, lfield);
  958. X                leavescope
  959. X                end;
  960. X              sarrow:
  961. X                begin
  962. X                tp := mknode(nderef);
  963. X                tp^.texps := varptr
  964. X                end
  965. X            end;(* case *)
  966. X            tp := pvariable(tp)
  967. X            end
  968. X        else begin
  969. X            tp := varptr;
  970. X            if tp^.tt = nid then
  971. X                begin
  972. X                tq := idup(tp);
  973. X                if tq <> nil then
  974. X                    if tq^.tt in [nfunc, nproc,
  975. X                            nparproc, nparfunc] then
  976. X                        begin
  977. X                        (* subroutine-call without
  978. X                           parameters *)
  979. X                        tp := mknode(ncall);
  980. X                        tp^.tcall := varptr;
  981. X                        tp^.taparm := nil
  982. X                        end
  983. X                end
  984. X             end;
  985. X        pvariable := tp
  986. X    end;
  987. X
  988. X    (*    Parse an expression.                    *)
  989. X    function pexpr;
  990. X
  991. X    var    tp,
  992. X        tq    : treeptr;
  993. X        nt    : treetyp;
  994. X        next    : boolean;
  995. X
  996. X        function padjust(tu, tr : treeptr) : treeptr;
  997. X        begin
  998. X            if pprio[tu^.tt] >= pprio[tr^.tt] then
  999. X                begin
  1000. X                if tr^.tt in [nnot, numinus, nuplus,
  1001. X                            nset, nderef] then
  1002. X                    tr^.texps := padjust(tu, tr^.texps)
  1003. X                else
  1004. X                    tr^.texpl := padjust(tu, tr^.texpl);
  1005. X                padjust := tr
  1006. X                end
  1007. X            else begin
  1008. X                if tu^.tt in [nnot, numinus, nuplus,
  1009. X                            nset, nderef] then
  1010. X                    tu^.texps := tr
  1011. X                else
  1012. X                    tu^.texpr := tr;
  1013. X                padjust := tu
  1014. X                 end
  1015. X        end;
  1016. X
  1017. X    begin
  1018. X        nextsymbol([sid, schar, sinteger, sreal, sstring, snil,
  1019. X                splus, sminus, snot, slpar, slbrack, srbrack]);
  1020. X        next := true;
  1021. X        case currsym.st of
  1022. X          splus:
  1023. X            begin
  1024. X            tp := mknode(nuplus);
  1025. X            tp^.texps := nil;
  1026. X            tp := pexpr(tp);
  1027. X            next := false
  1028. X            end;
  1029. X          sminus:
  1030. X            begin
  1031. X            tp := mknode(numinus);
  1032. X            tp^.texps := nil;
  1033. X            tp := pexpr(tp);
  1034. X            next := false
  1035. X            end;
  1036. X          snot:
  1037. X            begin
  1038. X            tp := mknode(nnot);
  1039. X            tp^.texps := nil;
  1040. X            tp := pexpr(tp);
  1041. X            next := false
  1042. X            end;
  1043. X          schar,
  1044. X          sinteger,
  1045. X          sreal,
  1046. X          sstring:
  1047. X            tp := mklit;
  1048. X          snil:
  1049. X            begin
  1050. X            usenilp := true;
  1051. X            tp := mknode(nnil);
  1052. X            end;
  1053. X          sid:
  1054. X            begin
  1055. X            tp := pvariable(oldid(currsym.vid, lidentifier));
  1056. X            next := false
  1057. X            end;
  1058. X          slpar:
  1059. X            begin
  1060. X            tp := mknode(nuplus);
  1061. X            tp^.texps := pexpr(nil)
  1062. X            end;
  1063. X          slbrack:
  1064. X            begin
  1065. X            usesets := true;
  1066. X            tp := mknode(nset);
  1067. X            tp^.texps := nil;
  1068. X            tq := nil;
  1069. X            repeat
  1070. X                if tq = nil then
  1071. X                    begin
  1072. X                    tq := pexpr(nil);
  1073. X                    tp^.texps := tq
  1074. X                    end
  1075. X                else begin
  1076. X                    tq^.tnext := pexpr(nil);
  1077. X                    tq := tq^.tnext
  1078. X                     end
  1079. X            until    currsym.st = srbrack;
  1080. X            end;
  1081. X          srbrack:
  1082. X            begin
  1083. X            tp := mknode(nempty);
  1084. X            next := false
  1085. X            end
  1086. X        end;
  1087. X        if next then
  1088. X            nextsymbol([
  1089. X                scolon, ssemic, scomma, sdotdot, srpar, srbrack,
  1090. X                sle, slt, seq, sge, sgt, sne,
  1091. X                splus, sminus, smul, sdiv, smod, squot,
  1092. X                sand, sor, sinn,
  1093. X                send, suntil, sthen, selse, sdo, sdownto, sto,
  1094. X                sof, slpar, slbrack]);
  1095. X        case currsym.st of
  1096. X          sdotdot:
  1097. X            nt := nrange;
  1098. X          splus:
  1099. X            nt := nplus;
  1100. X          sminus:
  1101. X            nt := nminus;
  1102. X          smul:
  1103. X            nt := nmul;
  1104. X          sdiv:
  1105. X            nt := ndiv;
  1106. X          smod:
  1107. X            nt := nmod;
  1108. X          squot:
  1109. X            begin
  1110. X            defnams[dreal]^.lused := true;
  1111. X            nt := nquot;
  1112. X            end;
  1113. X          sand:
  1114. X            nt := nand;
  1115. X          sor:
  1116. X            nt := nor;
  1117. X          sinn:
  1118. X            begin
  1119. X            nt := nin;
  1120. X            usesets := true
  1121. X            end;
  1122. X          sle:
  1123. X            nt := nle;
  1124. X          slt:
  1125. X            nt := nlt;
  1126. X          seq:
  1127. X            nt := neq;
  1128. X          sge:
  1129. X            nt := nge;
  1130. X          sgt:
  1131. X            nt := ngt;
  1132. X          sne:
  1133. X            nt := nne;
  1134. X          scolon:
  1135. X            nt := nformat;
  1136. X          sid, schar, sinteger, sreal, sstring, snil,
  1137. X          ssemic, scomma, slpar, slbrack, srpar, srbrack,
  1138. X          send, suntil, sthen, selse, sdo, sdownto, sto, sof:
  1139. X            nt := nnil
  1140. X        end;(* case *)
  1141. X        if nt in [nin .. nor, nand, nnot] then
  1142. X            defnams[dboolean]^.lused := true;
  1143. X        if nt <> nnil then
  1144. X            begin
  1145. X            (* binary operator *)
  1146. X            tq := mknode(nt);
  1147. X            tq^.texpl := tp;
  1148. X            tq^.texpr := nil;
  1149. X            tp := pexpr(tq)
  1150. X            end;
  1151. X
  1152. X        (* this statement yilds proper operator precedence *)
  1153. X        if tnp <> nil then
  1154. X            tp := padjust(tnp, tp);
  1155. X        pexpr := tp
  1156. X    end;
  1157. X
  1158. X    (*    Parse a case-statement.                    *)
  1159. X    function pcase;
  1160. X
  1161. X    label    999;
  1162. X
  1163. X    var    tp,
  1164. X        tq,
  1165. X        tv    : treeptr;
  1166. X
  1167. X    begin
  1168. X        tp := mknode(ncase);
  1169. X        tp^.tcasxp := pexpr(nil);
  1170. X        checksymbol([sof]);
  1171. X        tq := nil;
  1172. X        repeat
  1173. X            if tq = nil then
  1174. X                begin
  1175. X                tq := mknode(nchoise);
  1176. X                tp^.tcaslst := tq
  1177. X                end
  1178. X            else begin
  1179. X                tq^.tnext := mknode(nchoise);
  1180. X                tq := tq^.tnext
  1181. X                 end;
  1182. X            tv := nil;
  1183. X            repeat
  1184. X                nextsymbol([sid, sinteger, schar,
  1185. X                        splus, sminus, send, sother]);
  1186. X                if currsym.st in [send, sother] then
  1187. X                    goto 999;
  1188. X                if tv = nil then
  1189. X                    begin
  1190. X                    tv := pconstant(false);
  1191. X                    tq^.tchocon := tv
  1192. X                    end
  1193. X                else begin
  1194. X                    tv^.tnext := pconstant(false);
  1195. X                    tv := tv^.tnext
  1196. X                     end;
  1197. X                nextsymbol([scomma, scolon])
  1198. X            until    currsym.st = scolon;
  1199. X            tq^.tchostmt := plabstmt
  1200. X        until    currsym.st = send;
  1201. X    999:
  1202. X        if currsym.st = sother then
  1203. X            begin
  1204. X            nextsymbol([scolon, sid, sif, swhile, srepeat, sfor,
  1205. X                    scase, swith, sbegin, sgoto,
  1206. X                    selse, ssemic, send, suntil]);
  1207. X            if currsym.st = scolon then
  1208. X                nextsymbol([sid, sif, swhile, srepeat, sfor,
  1209. X                    scase, swith, sbegin, sgoto,
  1210. X                    selse, ssemic, send, suntil]);
  1211. X            tp^.tcasother := pstmt
  1212. X            end
  1213. X        else begin
  1214. X            tp^.tcasother := nil;
  1215. X            usecase := true
  1216. X             end;
  1217. X        nextsymbol([ssemic, send, selse, suntil]);
  1218. X        pcase := tp
  1219. X    end;
  1220. X
  1221. X    (*    Parse an if-statement.                    *)
  1222. X    function pif;
  1223. X
  1224. X    var    tp    : treeptr;
  1225. X
  1226. X    begin
  1227. X        tp := mknode(nif);
  1228. X        tp^.tifxp := pexpr(nil);
  1229. X        checksymbol([sthen]);
  1230. X        tp^.tthen := plabstmt;
  1231. X        if currsym.st = selse then
  1232. X            tp^.telse := plabstmt
  1233. X        else
  1234. X            tp^.telse := nil;
  1235. X        pif := tp;
  1236. X    end;
  1237. X
  1238. X    (*    Parse a while-statement.                *)
  1239. X    function pwhile;
  1240. X
  1241. X    var    tp    : treeptr;
  1242. X
  1243. X    begin
  1244. X        tp := mknode(nwhile);
  1245. X        tp^.twhixp := pexpr(nil);
  1246. X        checksymbol([sdo]);
  1247. X        tp^.twhistmt := plabstmt;
  1248. X        pwhile := tp;
  1249. X    end;
  1250. X
  1251. X    (*    Parse a repeat-statement.                *)
  1252. X    function prepeat;
  1253. X
  1254. X    var    tp,
  1255. X        tq    : treeptr;
  1256. X
  1257. X    begin
  1258. X        tp := mknode(nrepeat);
  1259. X        tq := nil;
  1260. X        repeat
  1261. X            if tq = nil then
  1262. X                begin
  1263. X                tq := plabstmt;
  1264. X                tp^.treptstmt := tq
  1265. X                end
  1266. X            else begin
  1267. X                tq^.tnext := plabstmt;
  1268. X                tq := tq^.tnext
  1269. X                 end;
  1270. X            checksymbol([ssemic, suntil])
  1271. X        until    currsym.st = suntil;
  1272. X        tp^.treptxp := pexpr(nil);
  1273. X        prepeat := tp
  1274. X    end;
  1275. X
  1276. X    (*    Parse a for-statement.                    *)
  1277. X    function pfor;
  1278. X
  1279. X    var    tp    : treeptr;
  1280. X
  1281. X    begin
  1282. X        tp := mknode(nfor);
  1283. X        nextsymbol([sid]);
  1284. X        tp^.tforid := oldid(currsym.vid, lidentifier);
  1285. X        nextsymbol([sassign]);
  1286. X        tp^.tfrom := pexpr(nil);
  1287. X        checksymbol([sdownto, sto]);
  1288. X        tp^.tincr := currsym.st = sto;
  1289. X        tp^.tto := pexpr(nil);
  1290. X        checksymbol([sdo]);
  1291. X        tp^.tforstmt := plabstmt;
  1292. X        pfor := tp
  1293. X    end;
  1294. X
  1295. X    (*    Parse a with-statement.                    *)
  1296. X    function pwith;
  1297. X
  1298. X    var    tp,
  1299. X        tq    : treeptr;
  1300. X
  1301. X    begin
  1302. X        tp := mknode(nwith);
  1303. X        tq := nil;
  1304. X        repeat
  1305. X            if tq = nil then
  1306. X                begin
  1307. X                tq := mknode(nwithvar);
  1308. X                tp^.twithvar := tq
  1309. X                end
  1310. X            else begin
  1311. X                tq^.tnext := mknode(nwithvar);
  1312. X                tq := tq^.tnext
  1313. X                 end;
  1314. X            enterscope(nil);
  1315. X            tq^.tenv := currscope;
  1316. X            tq^.texpw := pexpr(nil);
  1317. X            scopeup(tq^.texpw);
  1318. X            checksymbol([scomma, sdo])
  1319. X        until    currsym.st = sdo;
  1320. X        tp^.twithstmt := plabstmt;
  1321. X        tq := tp^.twithvar;
  1322. X        while tq <> nil do
  1323. X            begin
  1324. X            leavescope;
  1325. X            tq := tq^.tnext
  1326. X            end;
  1327. X        pwith := tp
  1328. X    end;
  1329. X
  1330. X    (*    Parse a goto-statement.                    *)
  1331. X    function pgoto;
  1332. X
  1333. X    var    tp    : treeptr;
  1334. X
  1335. X    begin
  1336. X        nextsymbol([sinteger]);
  1337. X        tp := mknode(ngoto);
  1338. X        tp^.tlabel := oldlbl(false);
  1339. X        nextsymbol([ssemic, send, suntil, selse]);
  1340. X        pgoto := tp
  1341. X    end;
  1342. X
  1343. X    (*    Parse a begin-statement.                *)
  1344. X    function pbegin;
  1345. X
  1346. X    var    tp,
  1347. X        tq    : treeptr;
  1348. X
  1349. X    begin
  1350. X        tq := nil;
  1351. X        repeat
  1352. X            if tq = nil then
  1353. X                begin
  1354. X                tq := plabstmt;
  1355. X                tp := tq
  1356. X                end
  1357. X            else begin
  1358. X                tq^.tnext := plabstmt;
  1359. X                tq := tq^.tnext
  1360. X                 end
  1361. X        until    currsym.st = send;
  1362. X        if retain then
  1363. X            begin
  1364. X            tq := mknode(nbegin);
  1365. X            tq^.tbegin := tp;
  1366. X            tp := tq
  1367. X            end;
  1368. X        nextsymbol([send, selse, suntil, sdot, ssemic]);
  1369. X        pbegin := tp
  1370. X    end;
  1371. X
  1372. Xbegin    (* parse *)
  1373. X    nextsymbol([spgm, sconst, stype, svar, sproc, sfunc]);
  1374. X    if currsym.st = spgm then
  1375. X        top := pprogram
  1376. X    else
  1377. X        top := pmodule;
  1378. X    nextsymbol([seof]);
  1379. Xend;    (* parse *)
  1380. X
  1381. X(*    Compute value for a node (which must be some kind of constant).    *)
  1382. Xfunction cvalof(tp : treeptr) : integer;
  1383. X
  1384. Xvar    v    : integer;
  1385. X    tq    : treeptr;
  1386. X
  1387. Xbegin
  1388. X    case tp^.tt of
  1389. X      nuplus:
  1390. X        cvalof := cvalof(tp^.texps);
  1391. X      numinus:
  1392. X        cvalof := - cvalof(tp^.texps);
  1393. X      nnot:
  1394. X        cvalof := 1 - cvalof(tp^.texps);
  1395. X      nid:
  1396. X        begin
  1397. X        tq := idup(tp);
  1398. X        if tq = nil then
  1399. X            fatal(etree);
  1400. X        tp := tp^.tsym^.lsymdecl;
  1401. X        case tq^.tt of
  1402. X          nscalar:
  1403. X            begin
  1404. X            v := 0;
  1405. X            tq := tq^.tscalid;
  1406. X            while tq <> nil do
  1407. X                if tq = tp then
  1408. X                    tq := nil
  1409. X                else begin
  1410. X                    v := v + 1;
  1411. X                    tq := tq^.tnext
  1412. X                     end;
  1413. X            cvalof := v
  1414. X            end;
  1415. X          nconst:
  1416. X            cvalof := cvalof(tq^.tbind);
  1417. X        end;(* case *)
  1418. X        end;
  1419. X      ninteger:
  1420. X        cvalof := tp^.tsym^.linum;
  1421. X      nchar:
  1422. X        cvalof := ord(tp^.tsym^.lchar);
  1423. X    end (* case *)
  1424. Xend;    (* cvalof *)
  1425. X
  1426. X(*    Compute lower value of subrange or scalar type.            *)
  1427. Xfunction clower(tp : treeptr) : integer;
  1428. X
  1429. Xvar    tq    : treeptr;
  1430. X
  1431. Xbegin
  1432. X    tq := typeof(tp);
  1433. X    if tq^.tt = nscalar then
  1434. X        clower := scalbase
  1435. X    else if tq^.tt = nsubrange then
  1436. X        if tq^.tup^.tt = nconfarr then
  1437. X            clower := 0
  1438. X        else
  1439. X            clower := cvalof(tq^.tlo)
  1440. X    else if tq = typnods[tchar] then
  1441. X        clower := 0
  1442. X    else if tq = typnods[tinteger] then
  1443. X        clower := -maxint
  1444. X    else
  1445. X        fatal(etree)
  1446. Xend;    (* clower *)
  1447. X
  1448. X(*    Compute upper value of subrange or scalar type.            *)
  1449. Xfunction cupper(tp : treeptr) : integer;
  1450. X
  1451. Xvar    tq    : treeptr;
  1452. X    i    : integer;
  1453. X
  1454. Xbegin
  1455. X    tq := typeof(tp);
  1456. X    if tq^.tt = nscalar then
  1457. X        begin
  1458. X        tq := tq^.tscalid;
  1459. X        i := scalbase;
  1460. X        while tq^.tnext <> nil do
  1461. X            begin
  1462. X            i := i + 1;
  1463. X            tq := tq^.tnext
  1464. X            end;
  1465. X        cupper := i
  1466. X        end
  1467. X    else if tq^.tt = nsubrange then
  1468. X        if tq^.tup^.tt = nconfarr then
  1469. X            fatal(euprconf)
  1470. X        else
  1471. X            cupper := cvalof(tq^.thi)
  1472. X    else if tq = typnods[tchar] then
  1473. X        cupper := maxchar
  1474. X    else if tq = typnods[tinteger] then
  1475. X        cupper := maxint
  1476. X    else
  1477. X        fatal(etree)
  1478. Xend;    (* cupper *)
  1479. X
  1480. X(*    Compute the number of elements in a subrange.            *)
  1481. Xfunction crange(tp : treeptr) : integer;
  1482. X
  1483. Xbegin
  1484. X    crange := cupper(tp) - clower(tp) + 1
  1485. Xend;
  1486. X
  1487. X(*    Return number of words uset to store a set.            *)
  1488. Xfunction csetwords(i : integer) : integer;
  1489. X
  1490. Xbegin
  1491. X    i := (i+(setbits)) div (setbits+1);
  1492. X    if i > maxsetrange then
  1493. X        error(esetsize);
  1494. X    csetwords := i
  1495. Xend;
  1496. X
  1497. X(*    Return number of words uset to store a set.            *)
  1498. Xfunction csetsize(tp : treeptr) : integer;
  1499. X
  1500. Xvar    tq    : treeptr;
  1501. X    i    : integer;
  1502. X
  1503. Xbegin
  1504. X    tq := typeof(tp^.tof);
  1505. X    i := clower(tq);
  1506. X    (* bits in sets are always numbered from 0, so we (arbitrarily)
  1507. X       decide that the base must be in the first 6 words to avoid
  1508. X       unnecessary waste of space *)
  1509. X    if (i < 0) or (i >= 6 * (setbits+1))  then
  1510. X        error(esetbase);
  1511. X    csetsize := csetwords(crange(tq)) + 1
  1512. Xend;
  1513. X
  1514. X(*    Determine if tp is declared in the procedure it is used in.    *)
  1515. Xfunction islocal(tp : treeptr) : boolean;
  1516. X
  1517. Xvar    tq    : treeptr;
  1518. X
  1519. Xbegin
  1520. X    tq := tp^.tsym^.lsymdecl;
  1521. X    while not (tq^.tt in [nproc, nfunc, npgm]) do
  1522. X        tq := tq^.tup;
  1523. X    while not (tp^.tt in [nproc, nfunc, npgm]) do
  1524. X        tp := tp^.tup;
  1525. X    islocal := tp = tq
  1526. Xend;
  1527. X
  1528. X(*    Perform necessary transformations on tree and identifiers    *)
  1529. X(*    before generating code.                        *)
  1530. Xprocedure transform;
  1531. X
  1532. X
  1533. X    (*    Rename function when used as a variable.        *)
  1534. X    procedure renamf(tp : treeptr);
  1535. X
  1536. X    var    ip, iq    : symptr;
  1537. X        tq, tv    : treeptr;
  1538. X
  1539. X        (*    This procedure recursively descends the tree    *)
  1540. X        (*    and replaces function-assignments with variable    *)
  1541. X        (*    assignments.                    *)
  1542. X        procedure crtnvar(tp : treeptr);
  1543. X
  1544. X        begin
  1545. X            while tp <> nil do
  1546. X                begin
  1547. X                case tp^.tt of
  1548. X                  npgm:
  1549. X                    crtnvar(tp^.tsubsub);
  1550. X                  nfunc,
  1551. X                  nproc:
  1552. X                    begin
  1553. X                    crtnvar(tp^.tsubsub);
  1554. X                    crtnvar(tp^.tsubstmt)
  1555. X                    end;
  1556. X                  nbegin:
  1557. X                    crtnvar(tp^.tbegin);
  1558. X                  nif:
  1559. X                    begin
  1560. X                    crtnvar(tp^.tthen);
  1561. X                    crtnvar(tp^.telse)
  1562. X                    end;
  1563. X                  nwhile:
  1564. X                    crtnvar(tp^.twhistmt);
  1565. X                  nrepeat:
  1566. X                    crtnvar(tp^.treptstmt);
  1567. X                  nfor:
  1568. X                    crtnvar(tp^.tforstmt);
  1569. X                  ncase:
  1570. X                    begin
  1571. X                    crtnvar(tp^.tcaslst);
  1572. X                    crtnvar(tp^.tcasother)
  1573. X                    end;
  1574. X                  nchoise:
  1575. X                    crtnvar(tp^.tchostmt);
  1576. X                  nwith:
  1577. X                    crtnvar(tp^.twithstmt);
  1578. X                  nlabstmt:
  1579. X                    crtnvar(tp^.tstmt);
  1580. X                  nassign:
  1581. X                    begin
  1582. X                    (* revoke calls in assignment lhs, (mis-
  1583. X                       parsed due to ambiguous syntax) *)
  1584. X                    if tp^.tlhs^.tt = ncall then
  1585. X                        begin
  1586. X                        tp^.tlhs := tp^.tlhs^.tcall;
  1587. X                        tp^.tlhs^.tup := tp
  1588. X                        end;
  1589. X                    (* function name -> variable name *)
  1590. X                    tv := tp^.tlhs;
  1591. X                    if tv^.tt = nid then
  1592. X                        if tv^.tsym = ip then
  1593. X                            tv^.tsym := iq
  1594. X                    end;
  1595. X                  nbreak,
  1596. X                  npush,
  1597. X                  npop,
  1598. X                  ngoto,
  1599. X                  nempty,
  1600. X                  ncall:
  1601. X                    (* no op *)
  1602. X                end;(* case *)
  1603. X                tp := tp^.tnext
  1604. X                end
  1605. X        end;
  1606. X
  1607. X    begin    (* renamf *)
  1608. X        while tp <> nil do
  1609. X            begin
  1610. X            case tp^.tt of
  1611. X              npgm,
  1612. X              nproc:
  1613. X                renamf(tp^.tsubsub);
  1614. X              nfunc:
  1615. X                begin
  1616. X                (* create a variable to hold return value *)
  1617. X                tq := mknode(nvar);
  1618. X                tq^.tattr := aregister;
  1619. X                tq^.tup := tp;
  1620. X                tq^.tidl := newid(mkvariable('R'));
  1621. X                tq^.tidl^.tup := tq;
  1622. X                tq^.tbind := tp^.tfuntyp;
  1623. X                (* put it FIRST among variables, see esubr() *)
  1624. X                tq^.tnext := tp^.tsubvar;
  1625. X                tp^.tsubvar := tq;
  1626. X
  1627. X                iq := tq^.tidl^.tsym;
  1628. X                ip := tp^.tsubid^.tsym;
  1629. X                crtnvar(tp^.tsubsub);
  1630. X                crtnvar(tp^.tsubstmt);
  1631. X                (* process inner functions *)
  1632. X                renamf(tp^.tsubsub)
  1633. X                end;
  1634. X            end;(* case *)
  1635. X            tp := tp^.tnext
  1636. X            end
  1637. X    end;    (* renamf *)
  1638. X
  1639. X    (*    This procedure rearranges the tree such that multiple    *)
  1640. X    (*    vardeclarations don't have (structured) types attached    *)
  1641. X    (*    to them. If such a declararation is found, a new name    *)
  1642. X    (*    is created and the type is moved to the type section.    *)
  1643. X    procedure extract(tp : treeptr);
  1644. X
  1645. X    var    vp    : treeptr;
  1646. X
  1647. X        (*    Create a declaration for tp, enter in pp type-    *)
  1648. X        (*    list and return an identifier referencing it.    *)
  1649. X        function xtrit(tp, pp : treeptr; last : boolean) : treeptr;
  1650. X
  1651. X        var    np, rp    : treeptr;
  1652. X            ip    : idptr;
  1653. X
  1654. X        begin
  1655. X            (* create new declaration *)
  1656. X            np := mknode(ntype);
  1657. X            ip := mkvariable('T');
  1658. X            np^.tidl := newid(ip);
  1659. X            np^.tidl^.tup := np;
  1660. X
  1661. X            (* create substitute id *)
  1662. X            rp := oldid(ip, lidentifier);
  1663. X            rp^.tup := tp^.tup;
  1664. X            rp^.tnext := tp^.tnext;
  1665. X
  1666. X            (* steal type description *)
  1667. X            np^.tbind := tp;
  1668. X            tp^.tup := np;
  1669. X            tp^.tnext := nil;
  1670. X
  1671. X            (* add new declaration to tree *)
  1672. X            np^.tup := pp;
  1673. X            if last and (pp^.tsubtype <> nil) then
  1674. X                begin
  1675. X                pp := pp^.tsubtype;
  1676. X                while pp^.tnext <> nil do
  1677. X                    pp := pp^.tnext;
  1678. X                pp^.tnext := np
  1679. X                end
  1680. X            else begin
  1681. X                np^.tnext := pp^.tsubtype;
  1682. X                pp^.tsubtype := np;
  1683. X                end;
  1684. X
  1685. X            xtrit := rp;
  1686. X        end;
  1687. X
  1688. X        (*    Extract anonymous enumeration types.        *)
  1689. X        function xtrenum(tp, pp : treeptr) : treeptr;
  1690. X
  1691. X            (*    Name record-types referenced by ptrs.    *)
  1692. X            procedure nametype(tp : treeptr);
  1693. X
  1694. X            begin
  1695. X                tp := typeof(tp);
  1696. X                if tp^.tt = nrecord then
  1697. X                    if tp^.tuid = nil then
  1698. X                        tp^.tuid := mkvariable('S');
  1699. X            end;
  1700. X
  1701. X        begin
  1702. X            if tp <> nil then
  1703. X                begin
  1704. X                case tp^.tt of
  1705. X                  nfield,
  1706. X                  ntype,
  1707. X                  nvar:
  1708. X                    tp^.tbind :=
  1709. X                        xtrenum(tp^.tbind, pp);
  1710. X
  1711. X                  nscalar:
  1712. X                    if tp^.tup^.tt <> ntype then
  1713. X                        tp := xtrit(tp, pp, false);
  1714. X
  1715. X                  narray:
  1716. X                    begin
  1717. X                    tp^.taindx := xtrenum(tp^.taindx, pp);
  1718. X                    tp^.taelem := xtrenum(tp^.taelem, pp);
  1719. X                    end;
  1720. X                  nrecord:
  1721. X                    begin
  1722. X                    tp^.tflist := xtrenum(tp^.tflist, pp);
  1723. X                    tp^.tvlist := xtrenum(tp^.tvlist, pp);
  1724. X                    end;
  1725. X                  nvariant:
  1726. X                    tp^.tvrnt := xtrenum(tp^.tvrnt, pp);
  1727. X                  nfileof:
  1728. X                    tp^.tof := xtrenum(tp^.tof, pp);
  1729. X
  1730. X                  nptr:
  1731. X                    nametype(tp^.tptrid);
  1732. X
  1733. X                  nid,
  1734. X                  nsubrange,
  1735. X                  npredef,
  1736. X                  nempty,
  1737. X                  nsetof:
  1738. X                    (* no op *)
  1739. X                end;(* case *)
  1740. X                tp^.tnext := xtrenum(tp^.tnext, pp)
  1741. X                end;
  1742. X            xtrenum := tp
  1743. X        end;
  1744. X
  1745. X    begin    (* extract *)
  1746. X        while tp <> nil do
  1747. X            begin
  1748. X            (* tp points to a program/procedure/function node *)
  1749. X            tp^.tsubtype := xtrenum(tp^.tsubtype, tp);
  1750. X            tp^.tsubvar := xtrenum(tp^.tsubvar, tp);
  1751. X            vp := tp^.tsubvar;
  1752. X            while vp <> nil do
  1753. X                begin
  1754. X                (* variables of structured unnamed types *)
  1755. X                if vp^.tbind^.tt in [nscalar, narray,
  1756. X                            nrecord, nfileof] then
  1757. X                    vp^.tbind := xtrit(vp^.tbind, tp, true);
  1758. X                vp := vp^.tnext
  1759. X                end;
  1760. X            extract(tp^.tsubsub);
  1761. X            tp := tp^.tnext
  1762. X            end
  1763. X    end;    (* extract *)
  1764. X
  1765. X    (*    This procedure moves all local constants and types    *)
  1766. X    (*    used in nested procedures to the outermost declaration    *)
  1767. X    (*    level so that nested procedures may be extracted.    *)
  1768. X    procedure global(tp, dp : treeptr; depend : boolean);
  1769. X
  1770. X    label    555;
  1771. X
  1772. X    var    ip    : treeptr;
  1773. X        dep    : boolean;
  1774. X
  1775. X        (*    Mark all declared identifiers as unused.    *)
  1776. X        procedure markdecl(xp : treeptr);
  1777. X
  1778. X        begin
  1779. X            while xp <> nil do
  1780. X                begin
  1781. X                case xp^.tt of
  1782. X                  nid:
  1783. X                    xp^.tsym^.lused := false;
  1784. X                  nconst:
  1785. X                    markdecl(xp^.tidl);
  1786. X                  ntype,
  1787. X                  nvar,
  1788. X                  nvalpar,
  1789. X                  nvarpar,
  1790. X                  nfield:
  1791. X                    begin
  1792. X                    markdecl(xp^.tidl);
  1793. X                    if xp^.tbind^.tt <> nid then
  1794. X                        markdecl(xp^.tbind)
  1795. X                    end;
  1796. X                  nscalar:
  1797. X                    markdecl(xp^.tscalid);
  1798. X                  nrecord:
  1799. X                    begin
  1800. X                    markdecl(xp^.tflist);
  1801. X                    markdecl(xp^.tvlist)
  1802. X                    end;
  1803. X                  nvariant:
  1804. X                    markdecl(xp^.tvrnt);
  1805. X                  nconfarr:
  1806. X                    if xp^.tcelem^.tt <> nid then
  1807. X                        markdecl(xp^.tcelem);
  1808. X                  narray:
  1809. X                    if xp^.taelem^.tt <> nid then
  1810. X                        markdecl(xp^.taelem);
  1811. X                  nsetof,
  1812. X                  nfileof:
  1813. X                    if xp^.tof^.tt <> nid then
  1814. X                        markdecl(xp^.tof);
  1815. X                  nparproc,
  1816. X                  nparfunc:
  1817. X                    markdecl(xp^.tparid);
  1818. X                  nptr,
  1819. X                  nsubrange:
  1820. X                    (* no op *)
  1821. X                end;(* case *)
  1822. X                xp := xp^.tnext
  1823. X                end
  1824. X        end;    (* markdecl *)
  1825. X
  1826. X        (*    Move all marked declarations to global scope.    *)
  1827. X        function movedecl(tp : treeptr) : treeptr;
  1828. X
  1829. X        var    ip, np    : treeptr;
  1830. X            sp    : symptr;
  1831. X            move    : boolean;
  1832. X
  1833. X        begin
  1834. X            if tp <> nil then
  1835. X                begin
  1836. X                move := false;
  1837. X                case tp^.tt of
  1838. X                  nconst,
  1839. X                  ntype:
  1840. X                    ip := tp^.tidl
  1841. X                end;(* case *)
  1842. X                while ip <> nil do
  1843. X                    begin
  1844. X                    if ip^.tsym^.lused then
  1845. X                        begin
  1846. X                        move := true;
  1847. X                        sp := ip^.tsym;
  1848. X                        if sp^.lid^.inref > 1 then
  1849. X                          begin
  1850. X                            sp^.lid :=
  1851. X                            mkrename( 'M', sp^.lid);
  1852. X                            sp^.lid^.inref :=
  1853. X                                sp^.lid^.inref - 1
  1854. X                          end;
  1855. X                        ip := nil
  1856. X                        end
  1857. X                    else
  1858. X                        ip := ip^.tnext
  1859. X                    end;
  1860. X                if move then
  1861. X                    begin
  1862. X                    np := tp^.tnext;
  1863. X                    tp^.tnext := nil;
  1864. X                    ip := tp;
  1865. X                    while ip^.tt <> npgm do
  1866. X                        ip := ip^.tup;
  1867. X                    tp^.tup := ip;
  1868. X                    case tp^.tt of
  1869. X                      nconst:
  1870. X                        begin
  1871. X                        if ip^.tsubconst = nil then
  1872. X                            ip^.tsubconst := tp
  1873. X                        else begin
  1874. X                            ip := ip^.tsubconst;
  1875. X                            while ip^.tnext <> nil
  1876. X                                do ip := ip^.tnext;
  1877. X                            ip^.tnext := tp
  1878. X                             end
  1879. X                        end;
  1880. X                      ntype:
  1881. X                        begin
  1882. X                        if ip^.tsubtype = nil then
  1883. X                            ip^.tsubtype := tp
  1884. X                        else begin
  1885. X                            ip := ip^.tsubtype;
  1886. X                            while ip^.tnext <> nil
  1887. X                                do ip := ip^.tnext;
  1888. X                            ip^.tnext := tp
  1889. X                             end
  1890. X                        end
  1891. X                    end;(* case *)
  1892. X                    (* tp is moved, drop it and process
  1893. X                       remainder of declarationlist *)
  1894. X                    tp := movedecl(np)
  1895. X                    end
  1896. X                else
  1897. X                    tp^.tnext := movedecl(tp^.tnext)
  1898. X                end;
  1899. X            movedecl := tp
  1900. X        end;    (* movedecl *)
  1901. X
  1902. X        (*    This procedure lifts out variables/parameters    *)
  1903. X        (*    used in nested procedures/functions.        *)
  1904. X        procedure movevars(tp, vp : treeptr);
  1905. X
  1906. X        label    555;
  1907. X
  1908. X        var    ep, dp, np    : treeptr;
  1909. X            ip        : idptr;
  1910. X            sp        : symptr;
  1911. X
  1912. X            (*    Move a variable    declaration to global    *)
  1913. X            (*    var declaration lists.            *)
  1914. X            procedure moveglob(tp, dp : treeptr);
  1915. X
  1916. X            begin
  1917. X                while tp^.tt <> npgm do
  1918. X                    tp := tp^.tup;
  1919. X                dp^.tup := tp;
  1920. X                dp^.tnext := tp^.tsubvar;
  1921. X                tp^.tsubvar := dp
  1922. X            end;
  1923. X
  1924. X            (*    Create nodes for saving a global    *)
  1925. X            (*    pointer variable.            *)
  1926. X            function stackop(decl, glob, loc : treeptr) : treeptr;
  1927. X
  1928. X            var    op, ip, dp, tp    : treeptr;
  1929. X
  1930. X            begin
  1931. X                (* create a new variable to hold old value
  1932. X                   of the global variable during a call *)
  1933. X                ip := newid(mkvariable('F'));
  1934. X                case vp^.tt of
  1935. X                  nvarpar,
  1936. X                  nvalpar,
  1937. X                  nvar:
  1938. X                    begin
  1939. X                    dp := mknode(nvarpar);
  1940. X                    dp^.tattr := areference;
  1941. X                    dp^.tidl := ip;
  1942. X                    (* use same type as the global var *)
  1943. X                    dp^.tbind := decl^.tbind
  1944. X                    end;
  1945. X                  nparproc,
  1946. X                  nparfunc:
  1947. X                    begin
  1948. X                    dp := mknode(vp^.tt);
  1949. X                    dp^.tparid := ip;
  1950. X                    dp^.tparparm := nil;
  1951. X                    dp^.tpartyp := vp^.tpartyp
  1952. X                    end
  1953. X                end;(* case *)
  1954. X                ip^.tup := dp;
  1955. X
  1956. X                (* add variable to declarationlists *)
  1957. X                tp := decl;
  1958. X                while not (tp^.tt in [nproc, nfunc, npgm]) do
  1959. X                    tp := tp^.tup;
  1960. X                dp^.tup := tp;
  1961. X                if tp^.tsubvar = nil then
  1962. X                    tp^.tsubvar := dp
  1963. X                else begin
  1964. X                    tp := tp^.tsubvar;
  1965. X                    while tp^.tnext <> nil do
  1966. X                        tp := tp^.tnext;
  1967. X                    tp^.tnext := dp
  1968. X                     end;
  1969. X                dp^.tnext := nil;
  1970. X
  1971. X                (* create an assignment saving value *)
  1972. X                op := mknode(npush);
  1973. X                op^.tglob := glob;
  1974. X                op^.tloc := loc;
  1975. X                op^.ttmp := ip;
  1976. X                stackop := op
  1977. X            end;
  1978. X
  1979. X            (*    Take a "push" node, create "pop" node    *)
  1980. X            (*    and add both to tree.            *)
  1981. X            procedure addcode(tp, push : treeptr);
  1982. X
  1983. X            var    pop    : treeptr;
  1984. X
  1985. X            begin
  1986. X                pop := mknode(npop);
  1987. X                (* share variables with "push"-node *)
  1988. X                pop^.tglob := push^.tglob;
  1989. X                pop^.ttmp := push^.ttmp;
  1990. X                pop^.tloc := nil;
  1991. X
  1992. X                (* add npush to head of statement list *)
  1993. X                push^.tnext := tp^.tsubstmt;
  1994. X                tp^.tsubstmt := push;
  1995. X                push^.tup := tp;
  1996. X
  1997. X                (* add npop to end of statement list *)
  1998. X                while push^.tnext <> nil do
  1999. X                    push := push^.tnext;
  2000. X                push^.tnext := pop;
  2001. X                pop^.tup := tp
  2002. X            end;
  2003. X
  2004. X        begin    (* movevars *)
  2005. X            while vp <> nil do
  2006. X                begin
  2007. X                case vp^.tt of
  2008. X                  nvar,
  2009. X                  nvalpar,
  2010. X                  nvarpar:
  2011. X                    dp := vp^.tidl;
  2012. X                  nparproc,
  2013. X                  nparfunc:
  2014. X                    begin
  2015. X                    dp := vp^.tparid;
  2016. X                    if dp^.tsym^.lused then
  2017. X                        begin
  2018. X                        (* create a var declaration *)
  2019. X                        ep := mknode(vp^.tt);
  2020. X                        ep^.tparparm := nil;
  2021. X                        ep^.tpartyp := vp^.tpartyp;
  2022. X                        np := newid(mkrename('G',
  2023. X                                dp^.tsym^.lid));
  2024. X                        ep^.tparid := np;
  2025. X                        np^.tup := ep;
  2026. X                        (* swap id's and symbols *)
  2027. X                        sp := np^.tsym;
  2028. X                        ip := sp^.lid;
  2029. X                        np^.tsym^.lid := dp^.tsym^.lid;
  2030. X                        dp^.tsym^.lid := ip;
  2031. X                        np^.tsym := dp^.tsym;
  2032. X                        dp^.tsym := sp;
  2033. X                        np^.tsym^.lsymdecl := np;
  2034. X                        dp^.tsym^.lsymdecl := dp;
  2035. X                        (* make declaration global *)
  2036. X                        moveglob(tp, ep);
  2037. X                        (* add save/restore-code *)
  2038. X                        addcode(tp, stackop(vp, np, dp))
  2039. X                        end;
  2040. X                    goto 555
  2041. X                    end
  2042. X                end;(* case *)
  2043. X                while dp <> nil do
  2044. X                    begin
  2045. X                    if dp^.tsym^.lused then
  2046. X                        begin
  2047. X                        (* create a varpar declaration,
  2048. X                           (nvarpar will cause emit to
  2049. X                           treat the new identifier
  2050. X                           as a pointer) *)
  2051. X                        ep := mknode(nvarpar);
  2052. X                        ep^.tattr := areference;
  2053. X                        np := newid(mkrename('G',
  2054. X                                dp^.tsym^.lid));
  2055. X                        ep^.tidl := np;
  2056. X                        np^.tup := ep;
  2057. X                        ep^.tbind := vp^.tbind;
  2058. X                        if ep^.tbind^.tt = nid then
  2059. X                            ep^.tbind^.tsym^.lused
  2060. X                                := true;
  2061. X                        (* swap id's and symbols *)
  2062. X                        sp := np^.tsym;
  2063. X                        ip := sp^.lid;
  2064. X                        np^.tsym^.lid := dp^.tsym^.lid;
  2065. X                        dp^.tsym^.lid := ip;
  2066. X                        np^.tsym := dp^.tsym;
  2067. X                        dp^.tsym := sp;
  2068. X                        np^.tsym^.lsymdecl := np;
  2069. X                        dp^.tsym^.lsymdecl := dp;
  2070. X                        (* note that dp is referenced *)
  2071. X                        dp^.tup^.tattr := aextern;
  2072. X                        (* make declaration global *)
  2073. X                        moveglob(tp, ep);
  2074. X                        (* add save/restore-code *)
  2075. X                        addcode(tp, stackop(vp, np, dp))
  2076. X                        end;
  2077. X                    dp := dp^.tnext
  2078. X                    end;
  2079. X            555:
  2080. X                vp := vp^.tnext
  2081. X                end
  2082. X        end;    (* movevars *)
  2083. X
  2084. X        (*    Break out a local variable and set the register    *)
  2085. X        (*    attribute.                    *)
  2086. X        procedure registervar(tp : treeptr);
  2087. X
  2088. X        var    vp, xp    : treeptr;
  2089. X
  2090. X        begin
  2091. X            vp := idup(tp);
  2092. X            tp := tp^.tsym^.lsymdecl;
  2093. X            (* vp points to nvar node *)
  2094. X            if (vp^.tidl <> tp) or (tp^.tnext <> nil) then
  2095. X                begin
  2096. X                (* tp is not alone in list of identifiers,
  2097. X                   create a new nvar-node and hook up tp *)
  2098. X                xp := mknode(nvar);
  2099. X                xp^.tattr := anone;
  2100. X                xp^.tidl := tp;
  2101. X                tp^.tup := xp;
  2102. X                (* enter new nvar node among declarations *)
  2103. X                xp^.tup := vp^.tup;
  2104. X                xp^.tbind := vp^.tbind; (* borrow type *)
  2105. X                xp^.tnext := vp^.tnext;
  2106. X                vp^.tnext := xp;
  2107. X                (* break tp out of list of identifiers *)
  2108. X                if vp^.tidl = tp then
  2109. X                    vp^.tidl := tp^.tnext
  2110. X                else begin
  2111. X                    vp := vp^.tidl;
  2112. X                    while vp^.tnext <> tp do
  2113. X                        vp := vp^.tnext;
  2114. X                    vp^.tnext := tp^.tnext
  2115. X                     end;
  2116. X                tp^.tnext := nil
  2117. X                end;
  2118. X            (* tp is alone in this declaration, set attribute *)
  2119. X            if tp^.tup^.tattr = anone then
  2120. X                tp^.tup^.tattr := aregister
  2121. X        end;    (* registervar *)
  2122. X
  2123. X        (*    Check static declarationlevel for a label    *)
  2124. X        (*    used in a non-local goto.            *)
  2125. X        procedure cklevel(tp : treeptr);
  2126. X
  2127. X        begin
  2128. X            tp := tp^.tsym^.lsymdecl;
  2129. X            while not(tp^.tt in [npgm, nproc, nfunc]) do
  2130. X                tp := tp^.tup;
  2131. X            if tp^.tstat > maxlevel then
  2132. X                maxlevel := tp^.tstat
  2133. X        end;
  2134. X
  2135. X    begin    (* global *)
  2136. X        while tp <> nil do
  2137. X            begin
  2138. X            case tp^.tt of
  2139. X              nproc,
  2140. X              nfunc:
  2141. X                begin
  2142. X                (* procid/parameters/const/type/var not used *)
  2143. X                markdecl(tp^.tsubid);
  2144. X                markdecl(tp^.tsubpar);
  2145. X                markdecl(tp^.tsubconst);
  2146. X                markdecl(tp^.tsubtype);
  2147. X                markdecl(tp^.tsubvar);
  2148. X
  2149. X                (* mark those used in nested subroutines *)
  2150. X                global(tp^.tsubsub, tp, false);
  2151. X
  2152. X                (* move out variables used in inner scope *)
  2153. X                movevars(tp, tp^.tsubpar);
  2154. X                movevars(tp, tp^.tsubvar);
  2155. X                (* move out const/type used in inner scope *)
  2156. X                tp^.tsubtype := movedecl(tp^.tsubtype);
  2157. X                tp^.tsubconst := movedecl(tp^.tsubconst);
  2158. X
  2159. X                (* mark identifiers used in this subroutine *)
  2160. X                global(tp^.tsubstmt, tp, true);
  2161. X                global(tp^.tsubpar, tp, false);
  2162. X                global(tp^.tsubvar, tp, false);
  2163. X                global(tp^.tsubtype, tp, false);
  2164. X                global(tp^.tfuntyp, tp, false);
  2165. X                end;
  2166. X
  2167. X              npgm:
  2168. X                begin
  2169. X                markdecl(tp^.tsubconst);
  2170. X                markdecl(tp^.tsubtype);
  2171. X                markdecl(tp^.tsubvar);
  2172. X                global(tp^.tsubsub, tp, false);
  2173. X                global(tp^.tsubstmt, tp, true)
  2174. X                end;
  2175. X
  2176. X              nconst,
  2177. X              ntype,
  2178. X              nvar,
  2179. X              nfield,
  2180. X              nvalpar,
  2181. X              nvarpar:
  2182. X                begin
  2183. X                ip := tp^.tidl;
  2184. X                dep := depend;
  2185. X                while (ip <> nil) and not dep do
  2186. X                    begin
  2187. X                    (* for all used identifiers, propagate
  2188. X                       the use to their bindings *)
  2189. X                    if ip^.tsym^.lused then
  2190. X                        dep := true;
  2191. X                    ip := ip^.tnext
  2192. X                    end;
  2193. X                global(tp^.tbind, dp, dep);
  2194. X                end;
  2195. X              nparproc,
  2196. X              nparfunc:
  2197. X                begin
  2198. X                global(tp^.tparparm, dp, depend);
  2199. X                global(tp^.tpartyp, dp, depend)
  2200. X                end;
  2201. X              nsubrange:
  2202. X                begin
  2203. X                global(tp^.tlo, dp, depend);
  2204. X                global(tp^.thi, dp, depend)
  2205. X                end;
  2206. X              nvariant:
  2207. X                begin
  2208. X                global(tp^.tselct, dp, depend);
  2209. X                global(tp^.tvrnt, dp, depend)
  2210. X                end;
  2211. X              nrecord:
  2212. X                begin
  2213. X                global(tp^.tflist, dp, depend);
  2214. X                global(tp^.tvlist, dp, depend)
  2215. X                end;
  2216. X              nconfarr:
  2217. X                begin
  2218. X                global(tp^.tcindx, dp, depend);
  2219. X                global(tp^.tcelem, dp, depend)
  2220. X                end;
  2221. X              narray:
  2222. X                begin
  2223. X                global(tp^.taindx, dp, depend);
  2224. X                global(tp^.taelem, dp, depend)
  2225. X                end;
  2226. X              nfileof,
  2227. X              nsetof:
  2228. X                global(tp^.tof, dp, depend);
  2229. X              nptr:
  2230. X                global(tp^.tptrid, dp, depend);
  2231. X              nscalar:
  2232. X                global(tp^.tscalid, dp, depend);
  2233. X              nbegin:
  2234. X                global(tp^.tbegin, dp, depend);
  2235. X              nif:
  2236. X                begin
  2237. X                global(tp^.tifxp, dp, depend);
  2238. X                global(tp^.tthen, dp, depend);
  2239. X                global(tp^.telse, dp, depend)
  2240. X                end;
  2241. X              nwhile:
  2242. X                begin
  2243. X                global(tp^.twhixp, dp, depend);
  2244. X                global(tp^.twhistmt, dp, depend)
  2245. X                end;
  2246. X              nrepeat:
  2247. X                begin
  2248. X                global(tp^.treptstmt, dp, depend);
  2249. X                global(tp^.treptxp, dp, depend)
  2250. X                end;
  2251. X              nfor:
  2252. X                begin
  2253. X                ip := idup(tp^.tforid);
  2254. X                if ip^.tup^.tt in [nproc, nfunc] then
  2255. X                    registervar(tp^.tforid);
  2256. X                global(tp^.tforid, dp, depend);
  2257. X                global(tp^.tfrom, dp, depend);
  2258. X                global(tp^.tto, dp, depend);
  2259. X                global(tp^.tforstmt, dp, depend)
  2260. X                end;
  2261. X              ncase:
  2262. X                begin
  2263. X                global(tp^.tcasxp, dp, depend);
  2264. X                global(tp^.tcaslst, dp, depend);
  2265. X                global(tp^.tcasother, dp, depend)
  2266. X                end;
  2267. X              nchoise:
  2268. X                begin
  2269. X                global(tp^.tchocon, dp, depend);
  2270. X                global(tp^.tchostmt, dp, depend);
  2271. X                end;
  2272. X              nwith:
  2273. X                begin
  2274. X                global(tp^.twithvar, dp, depend);
  2275. X                global(tp^.twithstmt, dp, depend)
  2276. X                end;
  2277. X              nwithvar:
  2278. X                begin
  2279. X                ip := typeof(tp^.texpw);
  2280. X                if ip^.tuid = nil then
  2281. X                    ip^.tuid := mkvariable('S');
  2282. X                global(tp^.texpw, dp, depend);
  2283. X                end;
  2284. X              nlabstmt:
  2285. X                global(tp^.tstmt, dp, depend);
  2286. X              neq, nne, nlt, nle, ngt, nge:
  2287. X                begin
  2288. X                global(tp^.texpl, dp, depend);
  2289. X                global(tp^.texpr, dp, depend);
  2290. X                ip := typeof(tp^.texpl);
  2291. X                if (ip = typnods[tstring]) or
  2292. X                            (ip^.tt = narray) then
  2293. X                    usecomp := true;
  2294. X                ip := typeof(tp^.texpr);
  2295. X                if (ip = typnods[tstring]) or
  2296. X                            (ip^.tt = narray) then
  2297. X                    usecomp := true
  2298. X                end;
  2299. X              nin, nor, nplus, nminus,
  2300. X              nand, nmul, ndiv, nmod, nquot,
  2301. X              nformat, nrange:
  2302. X                begin
  2303. X                global(tp^.texpl, dp, depend);
  2304. X                global(tp^.texpr, dp, depend)
  2305. X                end;
  2306. X
  2307. X              nassign:
  2308. X                begin
  2309. X                global(tp^.tlhs, dp, depend);
  2310. X                global(tp^.trhs, dp, depend)
  2311. X                end;
  2312. X
  2313. X              nnot,
  2314. X              numinus,
  2315. X              nuplus,
  2316. X              nderef:
  2317. X                global(tp^.texps, dp, depend);
  2318. X              nset:
  2319. X                global(tp^.texps, dp, depend);
  2320. X              nindex:
  2321. X                begin
  2322. X                global(tp^.tvariable, dp, depend);
  2323. X                global(tp^.toffset, dp, depend)
  2324. X                end;
  2325. X              nselect:
  2326. X                global(tp^.trecord, dp, depend);
  2327. X              ncall:
  2328. X                begin
  2329. X                global(tp^.tcall, dp, depend);
  2330. X                global(tp^.taparm, dp, depend)
  2331. X                end;
  2332. X              nid:
  2333. X                begin
  2334. X                (* find declaration point *)
  2335. X                ip := idup(tp);
  2336. X                if ip = nil then
  2337. X                    goto 555;
  2338. X                (* ip points to nconst/ntype/nvar/nproc/nfunc/
  2339. X                   nvalpar/nvarpar/nparproc or nparfunc node,
  2340. X                   move to beginning of enclosing scope *)
  2341. X                repeat
  2342. X                    ip := ip^.tup;
  2343. X                    if ip = nil then
  2344. X                        goto 555
  2345. X                    (* stop only for locally declared items,
  2346. X                       for global or predefined identifiers
  2347. X                       we will have gone to label 555 *)
  2348. X                until    ip^.tt in [npgm, nproc, nfunc];
  2349. X                if dp = ip then
  2350. X                    begin
  2351. X                    (* identifier used here, mark it used *)
  2352. X                    if depend then
  2353. X                        tp^.tsym^.lused := true
  2354. X                    end
  2355. X                else begin
  2356. X                    (* identifier declared in enclosing
  2357. X                       scope, mark it used *)
  2358. X                    tp^.tsym^.lused := true
  2359. X                     end;
  2360. X            555:
  2361. X                end;
  2362. X              ngoto:
  2363. X                if not islocal(tp^.tlabel) then
  2364. X                    begin
  2365. X                    tp^.tlabel^.tsym^.lgo := true;
  2366. X                    usejmps := true;
  2367. X                    cklevel(tp^.tlabel)
  2368. X                    end;
  2369. X
  2370. X              nbreak,
  2371. X              npush,
  2372. X              npop,
  2373. X              npredef,
  2374. X              nempty,
  2375. X              nchar,
  2376. X              ninteger,
  2377. X              nreal,
  2378. X              nstring,
  2379. X              nnil:
  2380. X            end;(* case *)
  2381. X            tp := tp^.tnext
  2382. X            end
  2383. X    end;    (* global *)
  2384. X
  2385. X    (*    Rename identifiers identical to C keywords.        *)
  2386. X    procedure renamc;
  2387. X
  2388. X    var    ip    : idptr;
  2389. X        cn    : cnames;
  2390. X
  2391. X    begin
  2392. X        (* rename identifiers that mustn't be redefined
  2393. X           if C and Pascal semantix are to be preserved *)
  2394. X        for cn := cabort to cwrite do
  2395. X            begin
  2396. X            ip := mkrename('C', ctable[cn]);
  2397. X            ctable[cn]^.istr := ip^.istr
  2398. X            end
  2399. X    end;
  2400. X
  2401. X    (*    Rename subroutines declared in other subroutines such    *)
  2402. X    (*    that they can be moved to a global scope without name-    *)
  2403. X    (*    clashes.                        *)
  2404. X    procedure renamp(tp : treeptr; on : boolean);
  2405. X
  2406. X    var    sp    : symptr;
  2407. X
  2408. X    begin
  2409. X        (* tp points to subroutine-list *)
  2410. X        while tp <> nil do
  2411. X            begin
  2412. X            renamp(tp^.tsubsub, true);
  2413. X            if on and (tp^.tsubstmt <> nil) then
  2414. X                begin
  2415. X                (* change name of subroutine by prefixing
  2416. X                   a unique name *)
  2417. X                sp := tp^.tsubid^.tsym;
  2418. X                if sp^.lid^.inref > 1 then
  2419. X                    begin
  2420. X                    sp^.lid := mkrename('P', sp^.lid);
  2421. X                    sp^.lid^.inref := sp^.lid^.inref - 1
  2422. X                    end
  2423. X                end;
  2424. X            tp := tp^.tnext
  2425. X            end
  2426. X    end;
  2427. X
  2428. X    (*    Add initialization-code for file-variables.        *)
  2429. X    procedure initcode(tp : treeptr);
  2430. X
  2431. X    var    ti, tq, tu, tv    : treeptr;
  2432. X
  2433. X        (*    Determine if a type contains a file.        *)
  2434. X        function filevar(tp : treeptr) : boolean;
  2435. X
  2436. X        var    fv    : boolean;
  2437. X            tq    : treeptr;
  2438. X
  2439. X        begin
  2440. X            case tp^.tt of
  2441. X              npredef:
  2442. X                fv := tp = typnods[ttext];
  2443. X              nfileof:
  2444. X                fv := true;
  2445. X              nconfarr:
  2446. X                fv := filevar(typeof(tp^.tcelem));
  2447. X              narray:
  2448. X                fv := filevar(typeof(tp^.taelem));
  2449. X              nrecord:
  2450. X                begin
  2451. X                fv := false;
  2452. X                tq := tp^.tvlist;
  2453. X                while tq <> nil do
  2454. X                    begin
  2455. X                    if filevar(tq^.tvrnt) then
  2456. X                        error(evrntfile);
  2457. X                    tq := tq^.tnext
  2458. X                    end;
  2459. X                tq := tp^.tflist;
  2460. X                while tq <> nil do
  2461. X                    begin
  2462. X                    if filevar(typeof(tq^.tbind)) then
  2463. X                        begin
  2464. X                        fv := true;
  2465. X                        tq := nil
  2466. X                        end
  2467. X                    else
  2468. X                        tq := tq^.tnext
  2469. X                    end
  2470. X                end;
  2471. X              nptr:
  2472. X                begin
  2473. X                fv := false;
  2474. X                if not tp^.tptrflag then
  2475. X                    begin
  2476. X                    tp^.tptrflag := true;
  2477. X                    if filevar(typeof(tp^.tptrid)) then
  2478. X                        error(evarfile);
  2479. X                    tp^.tptrflag := false
  2480. X                    end
  2481. X                end;
  2482. X              nsubrange,
  2483. X              nscalar,
  2484. X              nsetof:
  2485. X                fv := false
  2486. X            end;
  2487. X            filevar := fv
  2488. X        end;
  2489. X
  2490. X        (*    Create code for initialization of files.    *)
  2491. X        function fileinit(ti, tq : treeptr; opn : boolean) : treeptr;
  2492. X
  2493. X        var    tx, ty, tz    : treeptr;
  2494. X
  2495. X        begin
  2496. X            (* create 1 statement initializing "ti" *)
  2497. X            case tq^.tt of
  2498. X              narray:
  2499. X                begin
  2500. X                (* create declaration for a loopvariable *)
  2501. X                tz := newid(mkvariable('I'));
  2502. X                ty := mknode(nvar);
  2503. X                ty^.tattr := aregister;
  2504. X                ty^.tidl := tz;
  2505. X                ty^.tbind := typeof(tq^.taindx);
  2506. X                tz := tq;
  2507. X                while not(tz^.tt in [nproc, nfunc, npgm]) do
  2508. X                    tz := tz^.tup;
  2509. X                linkup(tz, ty);
  2510. X                if tz^.tsubvar = nil then
  2511. X                    tz^.tsubvar := ty
  2512. X                else begin
  2513. X                    tz := tz^.tsubvar;
  2514. X                    while tz^.tnext <> nil do
  2515. X                        tz := tz^.tnext;
  2516. X                    tz^.tnext := ty
  2517. X                     end;
  2518. X                ty := ty^.tidl;
  2519. X                (* create a loop initializing tq *)
  2520. X                tz := mknode(nindex);
  2521. X                tz^.tvariable := ti;
  2522. X                tz^.toffset := ty;
  2523. X                tz := fileinit(tz, tq^.taelem, opn);
  2524. X                tx := mknode(nfor);
  2525. X                tx^.tforid := ty;
  2526. X                ty := typeof(tq^.taindx);
  2527. X                if ty^.tt = nsubrange then
  2528. X                    begin
  2529. X                    tx^.tfrom := ty^.tlo;
  2530. X
  2531. END_OF_FILE
  2532. if test 52771 -ne `wc -c <'ptc.p.2'`; then
  2533.     echo shar: \"'ptc.p.2'\" unpacked with wrong size!
  2534. fi
  2535. # end of 'ptc.p.2'
  2536. fi
  2537. echo shar: End of archive 10 \(of 12\).
  2538. cp /dev/null ark10isdone
  2539. MISSING=""
  2540. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  2541.     if test ! -f ark${I}isdone ; then
  2542.     MISSING="${MISSING} ${I}"
  2543.     fi
  2544. done
  2545. if test "${MISSING}" = "" ; then
  2546.     echo You have unpacked all 12 archives.
  2547.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2548. else
  2549.     echo You still need to unpack the following archives:
  2550.     echo "        " ${MISSING}
  2551. fi
  2552. ##  End of shell archive.
  2553. exit 0
  2554. -- 
  2555.  
  2556. Rich $alz            "Anger is an energy"
  2557. Cronus Project, BBN Labs    rsalz@bbn.com
  2558. Moderator, comp.sources.unix    sources@uunet.uu.net
  2559.